package com.ikingtech.platform.service.log.controller;

import com.ikingtech.framework.sdk.context.event.TenantDeleteEvent;
import com.ikingtech.framework.sdk.context.security.Me;
import com.ikingtech.framework.sdk.context.exception.FrameworkException;
import com.ikingtech.framework.sdk.core.response.R;
import com.ikingtech.framework.sdk.log.api.LogApi;
import com.ikingtech.framework.sdk.log.model.*;
import com.ikingtech.framework.sdk.log.model.*;
import com.ikingtech.framework.sdk.log.model.rpc.AuthLogReportParam;
import com.ikingtech.framework.sdk.log.model.rpc.OperationLogReportParam;
import com.ikingtech.framework.sdk.log.model.rpc.SystemLogBatchReportParam;
import com.ikingtech.framework.sdk.utils.Tools;
import com.ikingtech.framework.sdk.web.annotation.ApiController;
import com.ikingtech.platform.service.log.entity.AuthLogDO;
import com.ikingtech.platform.service.log.entity.OperationLogDO;
import com.ikingtech.platform.service.log.entity.SystemLogDO;
import com.ikingtech.platform.service.log.service.AuthLogService;
import com.ikingtech.platform.service.log.service.OperationLogService;
import com.ikingtech.platform.service.log.service.SystemLogService;
import lombok.RequiredArgsConstructor;
import org.springframework.context.event.EventListener;

import java.util.List;


/**
 * @author tie yan
 */
@RequiredArgsConstructor
@ApiController(value = "/log", name = "日志中心", description = "日志中心")
public class LogController implements LogApi {

    private final AuthLogService authLogService;

    private final OperationLogService operationLogService;

    private final SystemLogService systemLogService;

    @Override
    public R<Object> reportAuthLog(AuthLogReportParam authLog) {
        AuthLogDO entity = Tools.Bean.copy(authLog, AuthLogDO.class);
        entity.setId(Tools.Id.uuid());
        this.authLogService.save(entity);
        return R.ok();
    }

    @Override
    public R<Object> deleteAuthLog(String id) {
        this.authLogService.removeById(id);
        return R.ok();
    }

    @Override
    public R<List<AuthLogDTO>> authLogPage(AuthLogQueryParamDTO queryParam) {
        return R.ok(this.authLogService.listPage(queryParam).convert(entity -> {
            AuthLogDTO log = Tools.Bean.copy(entity, AuthLogDTO.class);
            if (null != log.getType()) {
                log.setTypeName(log.getType().description);
            }
            return log;
        }));
    }

    @Override
    public R<List<AuthLogDTO>> listAuthLogByConditions(AuthLogQueryParamDTO queryParam) {
        return R.ok(Tools.Coll.convertList(this.authLogService.listByConditions(queryParam), entity -> {
            AuthLogDTO log = Tools.Bean.copy(entity, AuthLogDTO.class);
            if (null != log.getType()) {
                log.setTypeName(log.getType().description);
            }
            return log;
        }));
    }

    @Override
    public R<Object> reportOperationLog(OperationLogReportParam operationLog) {
        OperationLogDO entity = Tools.Bean.copy(operationLog, OperationLogDO.class);
        entity.setId(Tools.Id.uuid());
        entity.setTenantCode(Me.tenantCode());
        this.operationLogService.save(entity);
        return R.ok();
    }

    @Override
    public R<Object> deleteOperationLog(String id) {
        this.operationLogService.removeById(id);
        return R.ok();
    }

    @Override
    public R<List<OperationLogDTO>> operationLogPage(OperationLogQueryParamDTO queryParam) {
        return R.ok(this.operationLogService.listPage(queryParam).convert(entity -> Tools.Bean.copy(entity, OperationLogDTO.class)));
    }

    @Override
    public R<List<OperationLogDTO>> listOperationLogByConditions(OperationLogQueryParamDTO queryParam) {
        return R.ok(Tools.Coll.convertList(this.operationLogService.listByConditions(queryParam), entity -> Tools.Bean.copy(entity, OperationLogDTO.class)));
    }

    @Override
    public R<OperationLogDTO> operationLogDetail(String id) {
        OperationLogDO entity = operationLogService.getById(id);
        if (null == entity) {
            throw new FrameworkException("operationLogNotFound");
        }
        return R.ok(Tools.Bean.copy(entity, OperationLogDTO.class));
    }

    @Override
    public R<Object> reportSystemLog(SystemLogBatchReportParam systemLogs) {
        this.systemLogService.saveBatch(Tools.Coll.convertList(systemLogs.getLogReportParams(), log -> {
            SystemLogDO entity = Tools.Bean.copy(log, SystemLogDO.class);
            entity.setId(Tools.Id.uuid());
            entity.setTenantCode(Me.tenantCode());
            return entity;
        }));
        return R.ok();
    }

    @Override
    public R<Object> deleteSystemLog(String id) {
        this.systemLogService.removeById(id);
        return R.ok();
    }

    @Override
    public R<List<SystemLogDTO>> systemLogPage(SystemLogQueryParamDTO queryParam) {
        return R.ok(this.systemLogService.listPage(queryParam).convert(entity -> Tools.Bean.copy(entity, SystemLogDTO.class)));
    }

    @Override
    public R<SystemLogDTO> systemLogDetail(String id) {
        SystemLogDO entity = this.systemLogService.getById(id);
        if (null == entity) {
            throw new FrameworkException("systemLogNotFound");
        }
        return R.ok(Tools.Bean.copy(entity, SystemLogDTO.class));
    }

    @EventListener
    public void deleteTenantOperationLogEventListener(TenantDeleteEvent event) {
        this.operationLogService.removeByTenantCode(event.getCode());
    }

    @EventListener
    public void deleteTenantSystemLogEventListener(TenantDeleteEvent event) {
        this.systemLogService.removeByTenantCode(event.getCode());
    }
}
